//-----------------------------------------------------------------------------
//
//Copyright(c) 2020, ThorsianWay Technologies Co, Ltd
//All rights reserved.
//
//IP Name       :   raster
//File Name     :   coor_cnt.v
//Module name   :   coor_cnt
//Full name     :   calculate maximize coordinate for block
//
//Author        :   zha daolu
//Email         :   
//Data          :   2020/6/1
//Version       :   V1.00
//
//Abstract      :   
//                  
//Called  by    :   GPU
//
//Modification history
//-----------------------------------------------------
//1.00: intial version 
//
//-----------------------------------------------------------------------------

//-----------------------------
//DEFINE MACRO
//-----------------------------  
module coor_cnt
(
    input                       clk,                //input clock                           
    input                       rst_n,              //input reset, low active               
    input[6:0]                  position,           //input block code                 
    input[1:0]                  scale,              //input block size                      
    input busy,                                     //input next stage busy                    
    input[1:0]                      sym0,           //input ee parameter sign bit, [1] : b sign bit, [0] : a sign bit                    
    input[1:0]                      sym1,           //input ee parameter sign bit, [1] : b sign bit, [0] : a sign bit                   
    input[1:0]                      sym2,           //input ee parameter sign bit, [1] : b sign bit, [0] : a sign bit                   
    output reg[4:0]             lin_x0,             //output x coordinate maximize ee0 in this block 
    output reg[4:0]             lin_y0,             //output y coordinate maximize ee0 in this block 
    output reg[4:0]             lin_x1,             //output x coordinate maximize ee1 in this block 
    output reg[4:0]             lin_y1,             //output y coordinate maximize ee1 in this block 
    output reg[4:0]             lin_x2,             //output x coordinate maximize ee2 in this block 
    output reg[4:0]             lin_y2              //output y coordinate maximize ee2 in this block 
);                                                                            
                                                                       

wire[4:0]                       x0_temp;
wire[4:0]                       y0_temp;
wire[4:0]                       x1_temp;
wire[4:0]                       y1_temp;
wire[4:0]                       x2_temp;
wire[4:0]                       y2_temp;
wire[4:0]                       x3_temp;
wire[4:0]                       y3_temp;


reg[4:0]                        x0_l;
reg[4:0]                        y0_l;
reg[4:0]                        x1_l;
reg[4:0]                        y1_l;
reg[4:0]                        x2_l;
reg[4:0]                        y2_l;

//block left-right/bottom-top offset
reg[3:0]                xy_offset;

always@(*)
    begin
        case(scale)
              2'b00:    xy_offset  = 4'h0;
              2'b01:    xy_offset  = 4'h1;
              2'b10:    xy_offset  = 4'h3;
              2'b11:    xy_offset  = 4'h7;
            default:    xy_offset  = 4'h0;
        endcase
    end
    
//x/y0 left-bottom
//x/y1 right-bottom
//x/y2 right-top
//x/y3 left-top
assign x0_temp = {position[4],position[2],position[0],1'b0};    
assign y0_temp = {position[5],position[3],position[1],1'b0};        
assign x1_temp = {position[4],position[2],position[0],1'b0} + {1'b0,xy_offset} + 1'b1;
assign y1_temp = {position[5],position[3],position[1],1'b0};                
assign x2_temp = {position[4],position[2],position[0],1'b0} + {1'b0,xy_offset} + 1'b1;
assign y2_temp = {position[5],position[3],position[1],1'b0} + {1'b0,xy_offset} + 1'b1;
assign x3_temp = {position[4],position[2],position[0],1'b0};    
assign y3_temp = {position[5],position[3],position[1],1'b0} + {1'b0,xy_offset} + 1'b1;

//a>0&&b>0 right-top maximize ee
//a<0&&b>0 right-bottom maximize ee
//a<0&&b>0 left-top maximize ee
//a<0&&b<0 left-bottom maximize ee
always@(*)
    begin
        case(sym0)
              2'b00:    begin   x0_l = x2_temp;        y0_l = y2_temp;          end
              2'b01:    begin   x0_l = x1_temp;        y0_l = y1_temp;          end
              2'b10:    begin   x0_l = x3_temp;        y0_l = y3_temp;          end
              2'b11:    begin   x0_l = x0_temp;        y0_l = y0_temp;          end
            default:    begin   x0_l = 4'h0;          y0_l = 4'h0;              end
        endcase     
    end

    
always@(*)  
    begin   
        case(sym1)  
              2'b00:    begin   x1_l = x2_temp;        y1_l = y2_temp;          end
              2'b01:    begin   x1_l = x1_temp;        y1_l = y1_temp;          end
              2'b10:    begin   x1_l = x3_temp;        y1_l = y3_temp;          end
              2'b11:    begin   x1_l = x0_temp;        y1_l = y0_temp;          end
            default:    begin   x1_l = 4'h0;          y1_l = 4'h0;              end
        endcase                      
    end

    
always@(*)  
    begin   
        case(sym2)  
              2'b00:    begin   x2_l = x2_temp;        y2_l = y2_temp;          end 
              2'b01:    begin   x2_l = x1_temp;        y2_l = y1_temp;          end 
              2'b10:    begin   x2_l = x3_temp;        y2_l = y3_temp;          end 
              2'b11:    begin   x2_l = x0_temp;        y2_l = y0_temp;          end 
            default:    begin   x2_l = 4'h0;          y2_l = 4'h0;              end   
        endcase         
    end 


 

always@(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        begin
            lin_x0 <= 5'b0;
            lin_y0 <= 5'b0;
            lin_x1 <= 5'b0;
            lin_y1 <= 5'b0;
            lin_x2 <= 5'b0;
            lin_y2 <= 5'b0;
        end
    else if(~busy)
        begin
            lin_x0 <= x0_l;
            lin_y0 <= y0_l;
            lin_x1 <= x1_l;
            lin_y1 <= y1_l;
            lin_x2 <= x2_l;
            lin_y2 <= y2_l;    
        end     
end     
endmodule
    
    
    
    
    
    
    
    
